from urllib import request
from core.log import logging
import time
import json
def inspection(source:list,delay=0,timesleep=5,retry=5,timeout=5):
    '''inspection
        checking prepose service state. protocol of the sniffer must RESTful GET.
        
        Args:

        source: <list>,  will check service configuration.type of element value must dict. e.g. {"name":"","uri","header":{}}.

        delay: <int>, start inspection function on defiine delay seconds. default disable(0), set delay > 0 to make effective
        
        timesleep: <int>, retry interval time.

        retry: <int>, retry upper limit

        timeout: <int>, http time out. 
    '''
    if delay>0:
        time.sleep(delay)
    result= True
    retry_count=1
    if not source:
        return result,source
    for o in source:
        if 'code' not in o:
            o['code']= 500
            o['msg']='can not connected.'
    while (True and retry_count<=retry):
        logging.info("-------------------start inspection(%d)-------------------"%retry_count)
        for item in source:
            if item['code']==200:
                continue
            if 'header' in item:
                if "Content-Type" not in item["header"]:
                    item["header"]["Content-Type"]= "application/json"
                req= request.Request(item['uri'],headers=item['header'],method="GET")
            else:
                req= request.Request(item['uri'],method="GET")
            try:
                with request.urlopen(req,timeout=timeout) as res:
                    code= res.getcode()
                    body= res.read()
                    item["code"]=code
                    if code==200:
                        remote_result= json.loads(body)
                        if 'state' in remote_result:
                            if remote_result['state']==200:
                                if 'msg' in remote_result:
                                    logging.info("%s(%s) %s %s"%(item['name'],item["uri"],item["code"],remote_result['msg']))
                                    item["msg"]= "%s(%s) %s %s"%(item['name'],item["uri"],item["code"],remote_result['msg'])
                                else:
                                    logging.error("'%s' can not found 'msg' key."%item)
                                    item["msg"]= "%s(%s) %s %s"%(item['name'],item["uri"],item["code"],remote_result['msg'])
                            else:
                                logging.error("%s(%s) %s %s"%(item['name'],item["uri"],item["code"],remote_result['msg']))
                                item["msg"]= "%s(%s) %s %s"%(item['name'],item["uri"],item["code"],remote_result['msg'])
                                result= False
                        else:
                            logging.error("'%s' can not found 'state' key."%item)
                            item["msg"]= "%s(%s) %s %s"%(item['name'],item["uri"],item["code"],"can not found 'state' key.")
                            result= False
                    else:
                        logging.error("%s(%s) %s %s"%(item['name'],item["uri"],item["code"],remote_result['msg']))
                        item["msg"]= "%s(%s) %s %s"%(item['name'],item["uri"],item["code"],remote_result['msg'])
                        result= False
            except Exception as e:
                item["code"]=500
                logging.error("%s(%s) %s %s"%(item['name'],item["uri"],item["code"],e))
                item["msg"]= "%s(%s) %s %s"%(item['name'],item["uri"],item["code"],e)
                result= False
            if not result:
                break
        logging.info("-------------------end inspection(%d)-------------------"%retry_count)
        if  result:
            break
        else:
            time.sleep(timesleep)
            retry_count+=1
            if retry_count<= retry:
                result= True
    return result,source